<?php

class AccountsBalanceHistoryPortletAction {

    /**
     * 
     * Enter description here ...
     * @remotable
     */
    public function read($accountID, $range, $startDate, $endDate, $type) {
        $transactionDAO = DAOFactory::getTransactionDAO();
        $accountDAO = DAOFactory::getAccountDAO();

        $queryOptions = new TransactionExtDAOOptions();
        if ($type == 2)
            $queryOptions->onlyDestinationAccountID = true;
        else if ($type == 3)
            $queryOptions->onlySourceAccountID = true;

        switch ($range) {
            case 2:
                $now = new DateTime();
                $lastMonth = new DateTime();
                $lastMonth->modify("-30 day");
                $queryOptions->startDate = $lastMonth->format("Y-m-d");
                $queryOptions->endDate = $now->format("Y-m-d");
                break;
            case 3:
                $now = new DateTime();
                $lastMonth = new DateTime();
                $lastMonth->modify("-60 day");
                $queryOptions->startDate = $lastMonth->format("Y-m-d");
                $queryOptions->endDate = $now->format("Y-m-d");
                break;
            case 4:
                $startDayMonth = new DateTime();
                $endDayMonth = new DateTime();
                $startDayMonth->modify("first day");
                $endDayMonth->modify("last day");
                $queryOptions->startDate = $startDayMonth->format("Y-m-d");
                $queryOptions->endDate = $endDayMonth->format("Y-m-d");
                break;
            case 5:
                $startDayYear = new DateTime();
                $endDayYear = new DateTime();
                $startDayYear->modify("first day of this year");
                $endDayYear->modify("first day of next year");
                $endDayYear->modify("-1 day");
                $queryOptions->startDate = $startDayYear->format("Y-m-d");
                $queryOptions->endDate = $endDayYear->format("Y-m-d");
                break;
            case 6:
                $queryOptions->startDate = $startDate;
                $queryOptions->endDate = $endDate;
                break;
        }
        
        if ($accountID == null) {
            $accounts = $accountDAO->queryByAccountType('1');
        } else {
            $accounts = array( $accountDAO->load($accountID) );
        }            
        
        // Sum accounts initialAmount + transaction amount for every day. Eg. $resultDataByAccountByDate[$accountID][$date] = every transaction amount + inicial amount
        $resultDataByAccountByDate = array();
        $initialBalanceByAccount = array();
        foreach ($accounts as $account) {
            $queryOptions->accountID = $account->id;
            $transactions = $transactionDAO->queryTransactionsViewThroughOptions($queryOptions);
            $resultDataByAccountByDate[$account->id] = array();
            $balanceAmount = $initialBalanceByAccount[$account->id] = $account->initialAmount;            
            foreach ($transactions as $transaction) {
                $minDate = !isset($minDate) ? $minDate = $transaction->date : min($minDate, $transaction->date);
                $maxDate = !isset($maxDate) ? $maxDate = $transaction->date : max($maxDate, $transaction->date);

                if (!isset($resultDataByDate[$transaction->date]))
                    $resultDataByAccountByDate[$account->id][$transaction->date] = $balanceAmount;

                if ($transaction->sourceAccountID == $account->id) {
                    $resultDataByAccountByDate[$account->id][$transaction->date] -= $transaction->amount;
                    $balanceAmount -= $transaction->amount;
                } else if ($transaction->destinationAccountID == $account->id) {
                    $resultDataByAccountByDate[$account->id][$transaction->date] += $transaction->amount;
                    $balanceAmount += $transaction->amount;
                }
            }
        }
        
        // Create start and end dates (DateTime instance)		
        $startDate = $minDate;
        $startDate = explode('-', $startDate);
        $startDateDateTime = new DateTime();
        $startDateDateTime->setDate($startDate[0], $startDate[1], $startDate[2]);

        $endDate = $maxDate;
        $endDate = explode('-', $endDate);
        $endDateDateTime = new DateTime();
        $endDateDateTime->setDate($endDate[0], $endDate[1], $endDate[2]);
        $lastBalance = array();

        // Fill empty dates
        $troughtDate = $startDateDateTime;
        $resultDataByDate = array();
        $lastBalance = array();
        while ($troughtDate->format("Y-m-d") <= $endDateDateTime->format("Y-m-d")) {
            foreach ($resultDataByAccountByDate as $accountID => $array) {
                if (!array_key_exists($accountID, $lastBalance))
                    $lastBalance[$accountID] = $initialBalanceByAccount[$accountID];

                if (!array_key_exists($troughtDate->format("Y-m-d"), $resultDataByAccountByDate[$accountID])) {
                    $resultDataByAccountByDate[$accountID][$troughtDate->format("Y-m-d")] = $lastBalance[$accountID];
                } else {
                    $lastBalance[$accountID] = $resultDataByAccountByDate[$accountID][$troughtDate->format("Y-m-d")];
                }
            }
            $troughtDate->modify('+1 day');
        }

        // Sum accounts by date
        $resultDataByDate = array();
        foreach ($resultDataByAccountByDate as $account => $array) {
            foreach ($array as $date => $balance) {
                if (!isset($resultDataByDate[$date]))
                    $resultDataByDate[$date] = 0;
                $resultDataByDate[$date] += $balance;
            }
        }

        // Order by key
        ksort($resultDataByDate);

        // Transform output
        $resultData = array();
        foreach ($resultDataByDate as $date => $balance) {
            $explodedDate = explode('-', $date);
            $dateTime = new DateTime();
            $dateTime->setDate($explodedDate[0], $explodedDate[1], $explodedDate[2]);
            $resultData[] = array('date' => getJsTime($explodedDate[0], $explodedDate[1], $explodedDate[2], 0), 'amount' => $balance);
        }

        //array_splice( $resultData, 5 );

        $result = new ActionResult();
        $result->series = array('a', 'b', 'c');
        $result->data = $resultData;
        return $result;
    }

}

function getJsTime($year, $month, $day, $time) {
    $datestring = "$year-$month-$day-$time";
    return (strtotime($datestring) * 1000);    //convert the Unix time to JavaScript by multiplying by 1000 
}